「肉會往下掉,那是因為地心引力吧?可是在程式裡的資料結構,為什麼也要這樣設計?」我還是不死心,想把電腦和生活切得乾乾淨淨。
孩子忍不住撲哧笑出聲:「程式是人寫的呀,人腦袋裡怎麼想,就會怎麼帶進去。生活的經驗,本來就會滲到設計裡。」
我啞口無言,只能點點頭。
「行啦,你已經懂 Stack 的基本做法了。接下來,換我給你看另一種實現方式——用陣列結構來做 Stack!」
「雖然 Kotlin 本身有個 ArrayDeque,它不是專門的 Stack,但我們可以自己加幾個函式,把它變得更像。算是抄捷徑啦。」孩子說。
// 給 Kotlin 的 ArrayDeque 增加 Stack 風格的操作
fun <E> ArrayDeque<E>.push(element: E) = this.addLast(element)
fun <E> ArrayDeque<E>.pop(): E {
if (this.isEmpty()) throw NoSuchElementException("Stack is empty")
return this.removeLast()
}
fun <E> ArrayDeque<E>.peek(): E? = this.lastOrNull()
「這樣一來,我們就能用 push、pop、peek 這些『專屬 Stack』的名字來操作了。」他滿意地展示給我看,眼睛閃閃發光。
但我卻盯著程式碼皺起眉頭。
「等一下——為什麼是 ArrayDeque?不是 ArrayQueue 嗎?你確定沒有拼錯字?」
孩子愣了一下,隨即笑了:「Kotlin 沒有 ArrayQueue ,因為即使做出來能用的地方太少,效率也不好。所以他們另外做了 ArrayDeque, Deque 這個單字是 Double-Ended Queue 的縮寫,因為是 Double-Ended ,所以頭尾兩端都能新增、刪除,兩邊討好。因為這樣的特性,拿來實作 Stack 非常方便。」
我還是有點懷疑。
「要不然你實際看看結果啊?比起憑空想像會更清楚吧。」說著他就執行了操作 Stack 的程式碼。
fun main() {
val stack = ArrayDeque<String>()
// push
stack.push("A")
stack.push("B")
stack.push("C")
// pop
val popped = stack.pop()
println("Pop 出來: $popped")
// peek
val peeked = stack.peek()
println("Peek 頂端: $peeked")
// isEmpty
println("Stack 是否為空: ${stack.isEmpty()}")
}
執行結果正如孩子說的——後進先出:
Pop 出來: C
Peek 頂端: B
Stack 是否為空: false